/*
 * @Description: 开放字段上下文
 * @Author: Rfan
 * @Date: 2022-03-08 15:54:50
 * @LastEditTime: 2023-01-12 16:26:57
 */

import { createContext, useContext, useReducer } from 'react';
import { message, Modal } from 'antd';
import { OpeningReducer } from '../reducers/OpeningReducer';
import {
  ADD_OPENING,
  DELETE_OPENING,
  EDIT_OPENING,
  INIT_TABLE,
  SET_SELECTED_ITEM,
  SET_SELECT_AT,
  SET_SELECT_FOND,
  SET_SELECT_LEVEL,
  SET_OPENING_LIST,
  SET_SORT_TYPE
} from '../constants';
import {
  addOpening,
  deleteOpening,
  editOpening,
  fetchOpeningList
} from '@/api/rulesettings/ruleSetting';
import { getListItemValue } from '@/utils/list';
import { sortTypeList } from '../dictionaries';

const initialState = {
  // 当前选中的项目
  selectUnit: {},
  selectFond: {},
  selectAT: {},
  selectLevel: {},
  // 选中的表格条目
  selectItems: [],

  sortType: 1,
  // 列表相关
  list: [],
  // 检索tab列表
  retrieveList: [],

  dialog: {
    fieldList: []
  },

  // -------- 字典 --------
  // 开放字段显示状态列表
  visibleList: [
    { id: 0, name: '隐藏', color: '#faad14' },
    { id: 1, name: '显示', color: '#1890ff' }
  ],
  // 开放字段类型列表
  typeList: sortTypeList
};

const OpeningContext = createContext();

const OpeningContextProvider = (props) => {
  const [state, dispatch] = useReducer(OpeningReducer, initialState);

  const actions = {
    /**
     * @description: 设置选中的全宗
     * @param {*} data 选中的全宗对象
     */
    setSelectFond(data) {
      dispatch({ type: SET_SELECT_FOND, data });
    },

    /**
     * @description: 设置选中的档案类型
     * @param {*} data 选中的档案类型对象
     */
    setSelectAT(data) {
      dispatch({ type: SET_SELECT_AT, data });
    },

    /**
     * @description: 设置选中的层级
     * @param {*} data 选中的层级对象
     */
    setSelectLevel(data) {
      dispatch({ type: SET_SELECT_LEVEL, data });
    },

    /**
     * @description: 设置选中的层级
     * @param {*} data 选中的层级对象
     */
    setSortType(data) {
      dispatch({ type: SET_SORT_TYPE, data });
    },

    /**
     * @description: 将选中的条目id清空
     */
    clearSelectItems() {
      dispatch({ type: INIT_TABLE });
    },

    /**
     * @description: 设置表格中选中条目的key
     * @param {*} selectArr
     * @return {*}
     */
    setSelectKey(selectArr) {
      dispatch({ type: SET_SELECTED_ITEM, data: selectArr });
    },

    /**
     * @description: 获取排序列表
     * @param {*} listQuery 请求参数
     * @param {number} openingType 开放字段类型
     */
    getOpeningList(listQuery, openingType) {
      return new Promise((resolve, reject) => {
        fetchOpeningList(listQuery)
          .then((res) => {
            const data = res.data;
            dispatch({ type: SET_OPENING_LIST, data, openingType });
            resolve(data);
          })
          .catch((err) => {
            dispatch({ type: SET_OPENING_LIST, data: [], openingType });
            reject(err);
          });
      });
    },

    /**
     * @description: 直接设置列表
     * @param {object[]} data 设置的列表
     * @param {number} openingType 开放字段类型
     */
    setList(data, openingType) {
      dispatch({ type: SET_OPENING_LIST, data, openingType });
    },
    /**
     * @description: 增加排序字段
     * @param {*} query 请求参数
     * @param {number} openingType 开放字段类型
     */
    addOpeningFunc(query, openingType) {
      return new Promise((resolve, reject) => {
        addOpening(query)
          .then((res) => {
            const { data } = res;
            dispatch({ type: ADD_OPENING, data, openingType });
            resolve(data);
          })
          .catch((err) => reject(err));
      });
    },

    /**
     * @description: 编辑排序字段
     * @param {*} query 接口请求参数
     */
    editOpeningFunc(query) {
      return new Promise((resolve, reject) => {
        editOpening(query)
          .then((res) => {
            message.success('保存成功');
            const { data } = res;
            dispatch({ type: EDIT_OPENING, data, id: data?.rule?.id, openingType: query.type });
            resolve(data);
          })
          .catch((err) => reject(err));
      });
    },

    /**
     * @description: 更新字段排序
     * @param {any[]} queryList
     */
    updateOpeningSortFunc(queryList) {
      const promiseList = queryList.map((query) => editOpening(query));
      return new Promise((resolve, reject) => {
        Promise.all(promiseList)
          .then((resList) => {
            message.success('保存成功');
            resList.forEach((res) => {
              const { data } = res;
              dispatch({
                type: EDIT_OPENING,
                data,
                id: data?.rule?.id,
                openingType: data?.rule?.type
              });
            });
            resolve(resList);
          })
          .catch((err) => reject(err));
      });
    },

    /**
     * @description: 根据id、ids删除排序字段
     * @param {number|number[]} id 删除字段的id
     * @param {string} confirmContent 弹窗内容
     */
    deleteOpeningFunc(id, confirmContent = '确认删除选中的开放字段？') {
      Modal.confirm({
        title: '删除',
        content: confirmContent,
        onOk() {
          const ids = id instanceof Array ? id.join(',') : id;
          deleteOpening(ids).then((res) => {
            const data = res.data.map((id) => parseInt(id, 10));
            dispatch({ type: DELETE_OPENING, ids: data });
          });
        },
        onCancel() {}
      });
    }
  };

  const filters = {
    /**
     * @description: 是否可见过滤器
     * @param {*} id 是否可见状态
     * @return {*} 是否可见状态文案
     */
    visibleFilter(id) {
      return getListItemValue(id, state.visibleList);
    },

    /**
     * @description: 是否可见颜色过滤器
     * @param {*} id 是否可见状态
     * @return {*} 是否可见状态颜色
     */
    visibleColorFilter(id) {
      return getListItemValue(id, state.visibleList, 'color') || 'blue';
    },
    /**
     * @description: 开放字段类型过滤器
     * @param {*} id 开放字段类型
     * @return {*} 开放字段类型文案
     */
    typeFilter(id) {
      return getListItemValue(id, state.typeList);
    }
  };

  return (
    <OpeningContext.Provider value={{ ...state, ...actions, ...filters }}>
      {props.children}
    </OpeningContext.Provider>
  );
};

export const useOpeningContext = () => {
  return useContext(OpeningContext);
};

export { OpeningContext, OpeningContextProvider };
